//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	SecurityMatrix.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

namespace Smart.Common.Security
{
	/// <summary>
	/// Security matrix (define how to protect different kinds of securable objects)
	/// </summary>
	[Localizable(false)]
	public class SecurityMatrix
	{
		/// <summary>
		/// Matrix Name
		/// </summary>
		public string Name { get; set; }

		/// <summary>
		/// Security matrix rows (define how to protect different kinds of securable objects)
		/// </summary>
		public Dictionary<string, SecurityMatrixRow> Rows { get; set; }

		/// <summary>
		/// Security matrix (define how to protect different kinds of securable objects)
		/// </summary>
		public SecurityMatrix(string name)
		{
			Name = name;

			Rows = new Dictionary<string, SecurityMatrixRow>(StringComparer.OrdinalIgnoreCase);
		}

		/// <summary>
		/// Parse security matrix <paramref name="xml"/>
		/// </summary>
		/// <exception cref="FormatException">Root node 'Matrix' not found!</exception>
		/// <exception cref="FormatException">Row node should have attribute 'Name' specified!</exception>
		/// <exception cref="FormatException">Assignment node should have both attributes 'Principal' and 'AccessLevel' specified!</exception>
		public virtual void ParseXml(string xml)
		{
			XDocument doc;

			using (var stream = new StringReader(xml))
				doc = XDocument.Load(stream, LoadOptions.None);

			var root = doc.Root;

			if (root == null)
				throw new FormatException("Root node 'Matrix' not found!");

			foreach (var element in root.Elements())
			{
				if (element.NodeType != XmlNodeType.Element || !element.Name.LocalName.EqIC(@"Row"))
					continue;

				var row = new SecurityMatrixRow();

				row.ParseXml(element);

				Rows[row.Name] = row;
			}
		}
	}
}